#ifndef PARSER_LIST_H
#define PARSER_LIST_H

#include "ParserBase.h"

/**
 * This class handles all list commands.
 *
 * It currently does not support specific operations like "list next month"
 * or "list next week" or "list <date>"
 *
 * This is to be added in future edits.
 @author Ling Chun Kai
*/

using namespace std;
using namespace boost::posix_time;

class ParserList : public ParserBase {
public:
	ParserList(ParserBase* _nextParser);
private:
	enum {INSTRUCTION_POS = 1, ARGUMENTS_POS, NUM_MAJOR_SEGMENTS};

	// The following are regex constants used for parsing
	static const string regexInstructionAndArguments;

	static const string regexArgumentListAll;
	static const string regexArgumentListMonth;
	static const string regexArgumentListWeek;
	static const string regexArgumentListDay;
	static const string regexArgumentListSearchTerm;

	static const int ARGUMENT_POS_LIST_SEARCH_TERM = 1;

	// The following are the keywords allowed for instructions
	static const string regexInstructionList;
	
	bool tryParse(string userCommand, PARSED_COMMAND& parsedCommand);

	// This method takes a user command and splits it into the instruction and 
	// argument components
	bool getInstructionAndArguments(const string& userCommand, 
									string& instruction, 
									string& arguments);

	// This method checks that the instruction is of the type 'list'
	bool checkInstruction(const string& instruction);

	// This method parses the arguments provided to an add Instruction
	// and stores them in the PARSED_COMMAND struct passed.
	void parseList(PARSED_COMMAND& parsedCommand,
				  const string& arguments);

	// The following methods categorize the actual CommandType based on the arguments provided.
	// It returns the appropriate command type. matchingArguments will be 
	// filled up with the relevant details upon successful completion
	CommandType categorizeListCommand(const string& arguments, smatch& matchingArguments);

	// The following methods fill up the actual PARSED_COMMAND struct 
	// by reading. Additional parsing by individual methods may be required.
	// Returns true if the parsing was a success.
	void makeParsedCommandListAll(PARSED_COMMAND& parsedCommand, 
									   smatch& matchingArguments);
	void makeParsedCommandListMonth(PARSED_COMMAND& parsedCommand, 
									   smatch& matchingArguments);
	void makeParsedCommandListWeek(PARSED_COMMAND& parsedCommand, 
									   smatch& matchingArguments);
	void makeParsedCommandListDay(PARSED_COMMAND& parsedCommand, 
									   smatch& matchingArguments);
	void makeParsedCommandListSearchTerm(PARSED_COMMAND& parsedCommand, 
									   smatch& matchingArguments);
};

#endif